package com.iqunxing.redis.redisInAction.ch01;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import com.google.common.collect.Lists;

@Service
public class VoteService {

    private static final String ARTICLE_KEY = "article:";

    private static final String SCORE_KEY = "score:";

    private static final String VOTE_KEY = "vote:";

    private static final String TIME_KEY = "time:";

    private static final Long ONE_WEEK_IN_SECONDS = 7 * 86400L;

    private static final int VOTE_SCORE = 432;

    private static final int ARTICLES_PER_PAGE = 5;

    @Autowired
    private RedisTemplate<String, String> template;

    public String postArticle(String user, String title, String link) {
        Long incId = template.boundValueOps(ARTICLE_KEY).increment(1L);
        String articleId = String.valueOf(incId);
        BoundSetOperations<String, String> voteOps = template.boundSetOps(VOTE_KEY + articleId);
        voteOps.add(user);
        voteOps.expire(ONE_WEEK_IN_SECONDS, TimeUnit.SECONDS);
        long now = System.currentTimeMillis() / 1000;
        BoundHashOperations<String, String, Object> articleOps = template.boundHashOps(ARTICLE_KEY + articleId);
        articleOps.put("title", title);
        articleOps.put("link", link);
        articleOps.put("user", user);
        articleOps.put("now", String.valueOf(now));
        articleOps.put("votes", String.valueOf(1));
        Long score = now + VOTE_SCORE;
        template.boundZSetOps(SCORE_KEY).add(articleId, score);
        template.boundZSetOps(TIME_KEY).add(articleId, now);
        return articleId;
    }

    public void articleVote(String user, String articleId) {
        long cutoff = (System.currentTimeMillis() / 1000) - ONE_WEEK_IN_SECONDS;
        double postTime = template.boundZSetOps(TIME_KEY).score(String.valueOf(articleId));
        if (postTime < cutoff) {
            return;
        }
        Long addVoteResult = template.boundSetOps(VOTE_KEY + articleId).add(user);
        if (1 == addVoteResult) {
            template.boundZSetOps(SCORE_KEY).incrementScore(articleId, VOTE_SCORE);
            template.boundHashOps(ARTICLE_KEY + articleId).increment("votes", 1L);
        }
    }

    public List<Article> getArticle(int page) {
        List<Article> articles = Lists.newArrayList();
        int start = (page - 1) * ARTICLES_PER_PAGE;
        int end = start + ARTICLES_PER_PAGE - 1;

        Set<String> articleIds = template.boundZSetOps(SCORE_KEY).reverseRange(start, end);
        System.out.println("获取到的分数最高的五篇文章id--->" + articleIds);
        for (String articleId : articleIds) {
            Article article = new Article();
            article.setId(Long.valueOf(articleId));
            BoundHashOperations<String, String, Object> articleOps = template.boundHashOps(ARTICLE_KEY + articleId);
            Map<String, Object> entries = articleOps.entries();
            article.setTitle((String) entries.get("title"));
            article.setLink((String) entries.get("link"));
            article.setPoster((String) entries.get("user"));
            article.setTime(Long.valueOf((String) entries.get("now")));
            article.setVotes(Long.valueOf((String) entries.get("votes")));
            articles.add(article);
        }
        return articles;
    }

}
